﻿using System.IO;
using ExtendedStream;

namespace ExtendedStreamTester
{
    class Program
    {
        static void Main()
        {
            /*
            //Header Adding Test
            using (FileStream fileStream = File.OpenRead(@"c:\test.mp3"))
            {
                using (FileStream fileStream2 = File.OpenRead(@"c:\test2.mp3"))
                {
                    using (FileStream destination = File.OpenWrite(@"c:\test3.mp3"))
                    {
                        using (Stream headerdStream = fileStream.AddHeader(fileStream2))
                        {
                            headerdStream.CopyTo(destination);
                        }
                    }
                }
            }
            */

            /*
            //Sub Stream Test
            using (FileStream fileStream = File.OpenRead(@"c:\test.mp3"))
            {
                    using (FileStream destination = File.OpenWrite(@"c:\test3.mp3"))
                    {
                        using (Stream subStream = fileStream.SubStream(fileStream.Length / 2, fileStream.Length / 4))
                        {
                            subStream.CopyTo(destination);
                        }
                    }
            }
            */
            using (FileStream fileStream = File.OpenRead(@"c:\Big\Big.wav"))
            {
                using (Stream unlimitedWriteStream = new UnlimitedWriteStream(new DummyUnlimitedStreamProvider(@"c:\Big\Big.wav", 16 * 1024 * 1024)))
                {
                    fileStream.CopyTo(unlimitedWriteStream);
                }
            }            
        }
    }
    public class DummyUnlimitedStreamProvider:IUnlimitedStreamProvider
    {
        private readonly string _fileName;

        public DummyUnlimitedStreamProvider( string fileName, long limitation)
        {
            Limitation = limitation;
            _fileName = fileName;
        }

        #region Implementation of IUnlimitedStreamProvider

        public IUnlimitedStreamProviderData GetUnlimitedData(long index)
        {
            return new DummyUnlimitedStreamProviderData(File.Create(InsertStringAtTheEndOfPath(_fileName,index.ToString())),
                                                        true, new MemoryStream(new byte[] { 1, 2, 3 }), 
                                                        true, new MemoryStream(new byte[] { 3, 2, 1 }),
                                                        false,0);
        }

        private string InsertStringAtTheEndOfPath(string path,string value)
        {
            return path.Insert(path.Length - Path.GetExtension(path).Length, value);
        }
        public void OnUnlimitedStreamProviderDataWrote(IUnlimitedStreamProviderData unlimitedStreamProviderData, long index)
        {
            unlimitedStreamProviderData.Destination.Close();
        }

        public long Limitation { get; private set; }

        #endregion
    }

    public class DummyUnlimitedStreamProviderData:IUnlimitedStreamProviderData
    {
        private long _length;
        public DummyUnlimitedStreamProviderData(Stream destination, bool useTail, 
                                                Stream tail, bool useHeader, 
                                                Stream header, bool useLimitation, 
                                                long limitation)
        {
            Destination = destination;
            UseTail = useTail;
            Tail = tail;
            UseHeader = useHeader;
            Header = header;
            UseLimitation = useLimitation;
            Limitation = limitation;
            LimitationType = LimitationType.Method;
        }

        #region Implementation of IUnlimitedStreamProviderData

        public Stream Destination { get; private set; }
        public bool UseTail { get; private set; }
        public Stream Tail { get; private set; }
        public bool UseHeader { get; private set; }
        public Stream Header { get; private set; }
        public LimitationType LimitationType { get; private set; }
        public bool UseLimitation { get; private set; }
        public long Limitation { get; private set; }
        public int TryWriteData(byte[] buffer, int offset, int count)
        {
            int writesize =  1024 * 1024 - _length <= count ? (int)( 1024 * 1024 - _length) : count;
            _length += writesize;
            return writesize;
        }

        #endregion
    }
}
